import signal
from typing import Callable, Any, Awaitable


async def loop_until_terminated(iteration: Callable[[], Awaitable[Any]]):
    terminated = False

    def try_exit(signals, frame_type):
        nonlocal terminated
        if not terminated:
            terminated = True

    signal.signal(signal.SIGINT, try_exit)
    signal.signal(signal.SIGTERM, try_exit)

    while not terminated:
        await iteration()

